//引入其他的类
import Snake from './Snake'
import Food from './Food'
import ScorePanel from './ScorePanel'


// 游戏控制器， 控制其他的所有类
class GameControl{
    //定义三个属性
    //蛇
    snake:Snake;
    //食物
    food:Food;
    //记分牌
    scorePanel:ScorePanel;

    //创建属性来存储蛇的移动方向（也就是我们按键的方向）
    direction:string = '';

    //创建一个属性用来记录游戏是否结束
    islive = true;


    constructor() {
        this.snake = new Snake();
        this.food = new Food();
        this.scorePanel = new ScorePanel(10,3);   

        this.init()
    }

    //游戏的初始化方法，调用后游戏即开始
    init(){
        // 绑定键盘按键按下的事件
        //document.addEventListener('keydown', this.keydownHandler.bind(this)) //第一种解决方案-----调用bind(this) 创建一个新函数然后把（this）绑定成this.keydownHandler.bind(this)这个函数的this，所以（this）表示当前的对象 就不会有问题了
        document.addEventListener('keydown', this.keydownHandler) 
        //调用run方法 蛇移动
        this.run()

    }
    /**
     * 
     * ArrowUp  上   Up(IE)
     * ArrowDown 下  Down(IE)
     * ArrowLeft 左  Left(IE)
     * ArrowRight 右 Right(IE)
     */

    //创建一个键盘按下的响应函数
    // keydownHandler(event:KeyboardEvent){
       
    //     // 修改direction属性
    //     this.direction = event.key;

    // }

    //创建一个键盘按下的响应函数 //第二种解决方法改为箭头函数 解决this指向问题
    keydownHandler = (event:KeyboardEvent) =>{
        // 需要检查event.key的值是否合法（用户是否按了正确的按键)

        // 修改direction属性
        this.direction = event.key;
    }

    //创建一个控制蛇移动的方法
    run(){
        /**
         *  根据方向(this.direction) 来使蛇的位置改变
         *  向上    top值减小
         *  向下    top值增加    
         *  向左    left减小
         *  向右    left增加
         */
        // 获取蛇现在的坐标
        let X = this.snake.X;
        let Y = this.snake.Y;

        // 根据按键方向来修改X值和Y值
        switch(this.direction){
            //向上移动top减少
            case "ArrowUp":
            case "Up":
                Y -= 10;
                break;
            //向下移动top增加
            case "ArrowDown":
            case "Down":
                Y += 10;
                break;
            //向左移动left减少
            case "ArrowLeft":
            case "Left":
                X -= 10;
                break;
            //向右移动left增加
            case "ArrowRight":
            case "Right":
                X += 10;
                break;
        }

        // 检查蛇是否吃到了食物
        this.checkEat(X,Y) //运行蛇是否吃到食物
            
        
        //修改蛇的X和Y值
        try{
            this.snake.X = X; //调用snake的X和Y方法
            this.snake.Y = Y;
        }catch(e){
            // 进入到catch，说明出现了异常 游戏结束，弹出了一个弹窗提示消息
            alert(e.message + 'GAME OVER！');
            //将islive改为false
            this.islive = false //若是没有改为false会一直弹窗
        }
        

        //开启一个定时调用
        //第一种方法：setTimeout(this.run.bind(this),300)
        this.islive && setTimeout(()=>{  //加上this.islive &&判断 蛇还活着的时候才会继续动(this.islive==true)  蛇死了就不会动了(this.islive==false) 
            this.run()
        },300 - (this.scorePanel.level-1)*30) //根据等级来决定贪吃蛇的速度！！ 比如2级270 3级240 4级210
    }

    //定义一个方法，用来检查蛇是否吃到食物
    checkEat(X:number,Y:number){ //这个是蛇的新坐标
       if(X === this.food.X && Y === this.food.Y){ //这个是蛇的新坐标与食物坐标相等时，就是吃到了食物
            console.log('吃到食物了')
            // 吃到食物了 食物的位置要进行重置
            this.food.change();
            // 分数要增加
            this.scorePanel.addScore();
            // 蛇要增加一节
            this.snake.addBody();
       }  
    }





}

export default GameControl